/******************************************************************************
 * (C) Copyright 2013 Atech-Automotive
 * FILE NAME:    uds_diag_callback.c
 * DESCRIPTION:
 *
 * DATE BEGUN:   2015/05/05
 * BY:           hui.pang
 * PRODUCT NAME:
 * APPLICATION:
 * TARGET H/W:
 * DOC REF:
 *****************************************************************************
 */

/*****************************************************************************
** #include
*****************************************************************************/
#include "sys_micro.h"
#include "msg_CanType.h"
#include "system.h"
#include "uds_diag_callback.h"
#include "uds_diag_drv.h"
#include "uds_diag_fun.h"
#include "uds_diag_appl.h"
#include "drv_can.h"
#include "string.h"
#include "diag_cfg.h"
#include "diag.h"
#include "hwa_e2_callback.h"
#include "hwa_e2.h"
#pragma CODE_SEG _FAR_SEG OTHER_ROM

/*****************************************************************************
** #define
*****************************************************************************/


/*****************************************************************************
** typedef
*****************************************************************************/


/*****************************************************************************
** global variable
*****************************************************************************/


/*****************************************************************************
** static variables
*****************************************************************************/


/*****************************************************************************
** static constants
*****************************************************************************/


/*****************************************************************************
** static function prototypes
*****************************************************************************/


/*****************************************************************************
** function prototypes
*****************************************************************************/


/****************************************************************************/
/****************************************************************************/
/**
 * Function Name: UdsCallback_SendFrame
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2015/05/05, hui.pang create this function
 ****************************************************************************/
BOOL UdsCallback_SendFrame( UINT32 u32_id, UINT8 * p_u8_data, UINT8 u8_length )
{
    if(CAN_SUCCESS == drv_can_e_sendFrame(u32_id, 0, u8_length, p_u8_data))
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }   
}

/****************************************************************************/
/**
 * Function Name: UdsCallback_JumpBootload
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/10/20, LeLe.Zhu create this function
 ****************************************************************************/
void UdsCallback_JumpBootload(void)
{
//DY
    UINT16 *p_u16_boot_ram_flag;

#define BOOT_FLAG_ADDR   0x3000    
#define BOOT_FLAG        0x55AA

    p_u16_boot_ram_flag = (UINT16*)BOOT_FLAG_ADDR;
    *p_u16_boot_ram_flag = BOOT_FLAG;

    while( 1 ); /* wait for reset by watchdog */
}


/****************************************************************************/
/**
 * Function Name: UdsCallback_EcuReset
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/10/20, LeLe.Zhu create this function
 ****************************************************************************/
void UdsCallback_EcuReset(void) 
{ 
//    DIAG_ECU_RESET()  
    for(;;);
}

/****************************************************************************/
/**
 * Function Name: UdsCallback_CalcKey
 * Description: Calculate key to a given seed.
 *
 * Param:   none
 * Return:  none
 * Author:  2015/05/08, hui.pang create this function
 ****************************************************************************/

UINT32 UdsCallback_CalcKey(UINT32 u32_seed , UINT8 MASK)
{
    
    #define TOPBIT              0x8000
    #define POLYNOM_1           0x1021      /* CRC-CCITT  (Atech ADJ mode) */
    #define POLYNOM_1B          0x8408      /* CRC-XMODEM (Chery EOL mode) */
    #define POLYNOM_2           0x8025      /* non-standard */
    #define BITMASK             0x0080      /* non-standard */
    #define INITIAL_REMINDER    0xFFFE      /* non-standard */
    #define MSG_LEN             2           /* seed length in bytes */
    
    #define ADJ   5
    
    UINT8 bSeed[2];
    UINT16 remainder;
    UINT16 polynom_1;
    UINT8 n;
    UINT8 i;
    
    (void)MASK;
    
    bSeed[0] = (UINT8)(u32_seed >> 8); /* MSB */
    bSeed[1] = (UINT8)u32_seed;        /* LSB */
    remainder = INITIAL_REMINDER;
    
    if(MASK == ADJ) 
    {
        polynom_1 = POLYNOM_1;
    }
    else
    {
        polynom_1 = POLYNOM_1B;
    }
    
    for (n = 0; n < MSG_LEN; n++)
    {
        /* Bring the next byte into the remainder. */
        remainder ^= ((bSeed[n]) << 8);

        /* Perform modulo-2 division, a bit at a time. */
        for (i = 0; i < 8; i++)
        {
            /* Try to divide the current data bit. */
            if (remainder & TOPBIT)
            {
                if(remainder & BITMASK)
                {
                    remainder = (remainder << 1) ^ polynom_1;
                }
                else
                {
                    remainder = (remainder << 1) ^ POLYNOM_2;
                }
            }
            else
            {
                remainder = (remainder << 1);
            }
        }
    }
    /* The final remainder is the key */
    return remainder;
}

/****************************************************************************/
/**
 * Function Name: UdsCallback_OperationTimeOutClearFlag
 * Description: this function will clear flag if timed operation is timed
 *              out
 *
 * Param:   none
 * Return:  none
 * Author:  2015/05/08, hui.pang create this function
 ****************************************************************************/
void UdsCallback_OperationTimeOutClearFlag( void )
{
}

/****************************************************************************/
/**
 * Function Name: UdsCallback_GetRandomValueU32
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2015/05/28, hui.pang create this function
 ****************************************************************************/
UINT32 UdsCallback_GetRandomValueU32( void )
{
    UINT32 seed = 0;;
    (void)seed;
 //   seed = getRandomNumber();
    return (UINT32)seed;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_ReadE2Init
 * Description: none
 *
 * Param:   none
 * Return:  TRUE  - EE Reading is finished
 *          FALSE - Don't ready to read EE
 * Author:  2015/06/01, hui.pang create this function
 ****************************************************************************/
BOOL UdsCallBack_ReadE2Init( void )
{
    BOOL b_reponse = FALSE;

	b_reponse = TRUE;

    return b_reponse;
}

#ifdef MODE_2E_SUPPORTED

/****************************************************************************/
/**
 * Function Name: UdsCallback_WriteDataToE2
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2015/05/29, hui.pang create this function
 ****************************************************************************/
BOOL UdsCallback_WriteDataToE2(UdsAppl_WriteE2Type_E type, UINT32* p_u32_data)
{
    UINT8 rsponse = FALSE;
 //   (void)rsponse;        
    (void)p_u32_data;       
    (void)type;

	//////////////////////////////

	if( DIAG_E2_ADDR_VIN == type )
    {  
		    rsponse = hwa_e2WriteDataById(E2_ADDR_VIN_NUM_1, p_u32_data[0]);
		    rsponse = hwa_e2WriteDataById(E2_ADDR_VIN_NUM_2, p_u32_data[1]);
		    rsponse = hwa_e2WriteDataById(E2_ADDR_VIN_NUM_3, p_u32_data[2]);
		    rsponse = hwa_e2WriteDataById(E2_ADDR_VIN_NUM_4, p_u32_data[3]);
			rsponse = hwa_e2WriteDataById(E2_ADDR_VIN_NUM_5, p_u32_data[4]);
    }else if(DIAG_E2_ADDR_Application_Fingerprint_INFOR == type)
    {
        rsponse = hwa_e2WriteDataById(E2_ADDR_ECU_APPFINGER_NUM_1, p_u32_data[0]);
        rsponse = hwa_e2WriteDataById(E2_ADDR_ECU_APPFINGER_NUM_2, p_u32_data[1]);
        rsponse = hwa_e2WriteDataById(E2_ADDR_ECU_APPFINGER_NUM_3, p_u32_data[2]);
    }
    else  
    {
        rsponse = FALSE;
        /* do nothing */
    }

	//////////////////////////////

    return rsponse;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_GetE2IdleSts
 * Description: none
 *
 * Param:   none
 * Return:  TRUE  - E2 Idle
 *          FALSE - E2 Busy
 * Author:  2015/06/18, hui.pang create this function
 ****************************************************************************/
BOOL UdsCallBack_GetE2IdleSts( UdsAppl_WriteE2Type_E type, 
                                           UINT32 * p_u32_buff )
{
    (void)type;
    (void)p_u32_buff;
    
    //////////////////////////

//   if(E2_ADDR_PIN_ID == type)
//    {
//        if( (TRUE == hwa_e2ReadDataById(E2_ADDR_PIN, p_u32_buff))
//		  )
//        {
//            return TRUE;
//        }
//    }

    return FALSE;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_GetE2CompareState
 * Description: none
 *
 * Param:   none
 * Return:  TRUE  - E2 Compare OK
 *          FALSE - E2 Compare ERROR
 * Author:  2016/07/11, hui.liu create this function
 ****************************************************************************/
BOOL UdsCallBack_GetE2CompareState( UdsAppl_WriteE2Type_E type, 
                                                   UINT32* p_u32_data,
                                                   UINT32* p_u32_backup)
{
    (void)type;
    (void)p_u32_data;
    (void)p_u32_backup;
  
    /////////////////////////
//  
//	if(E2_ADDR_PIN_ID == type)
//    {
//        if(memcmp(p_u32_data, p_u32_backup, 4) == 0)
//        {
//            app_EmsAuth_v_setSharedElement(Shared_Pin,(UINT8*)p_u32_data);
//            return TRUE;
//        }
//    }

    return FALSE;
}
#endif // MODE_2E_SUPPORTED

#ifdef MODE_14_SUPPORTED

/****************************************************************************/
/**
 * Function Name: UdsCallBack_ClearAllDTCs
 * Description: none
 *
 * Param:   none
 * Return:  TRUE  - Clearing is finished
 *          FLASE - Clearing failure
 * Author:  2015/06/15, hui.pang create this function
 ****************************************************************************/
BOOL UdsCallBack_ClearAllDTCs( void )
{
    //Diag_ClearDTC();

    return TRUE;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_ClearPartDTCs
 * Description: none
 *
 * Param:   none
 * Return:  TRUE  - Clearing is finished
 *          FLASE - Clearing failure
 * Author:  2015/06/15, hui.pang create this function
 ****************************************************************************/
BOOL UdsCallBack_ClearSingleDTC( UINT16 DtcIndex )
{
	(void)DtcIndex;

#if 0
    
    diag_clearDtcByIndex(DtcIndex);

#endif
    return TRUE;
}

#endif// MODE_14_SUPPORTED

#ifdef MODE_85_SUPPORTED

/****************************************************************************/
/**
 * Function Name: UdsCallBack_StartStopDiag
 * Description: none
 *
 * Param b_start_flag: ON  - Start Diag
 *                     OFF - Stop Diag
 * Return:  none
 * Author:  2015/06/18, hui.pang create this function
 ****************************************************************************/
void UdsCallBack_StartStopDiag( BOOL b_start_flag )
{
	(void)b_start_flag;

	if( FALSE == b_start_flag )
	{
		ioctlDiagnostics(IOCTL_DTC_STOP);

	}
	else
	{
		ioctlDiagnostics(IOCTL_DTC_START);

	}
}

#endif// MODE_85_SUPPORTED

#ifdef MODE_19_SUPPORTED

/****************************************************************************/
/**
 * Function Name: UdsCallBack_GetSnapshotDtcRecodeSts
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/09/27, hui.liu create this function
 ****************************************************************************/
UINT8 UdsCallBack_GetSnapshotDtcRecodeSts(UINT16 u16_dtc_index , UINT8* pBuf)
{
    UINT8 u8_lenght = 0;
    (void)u16_dtc_index;
    (void)pBuf;

#if 0
    pBuf[u8_lenght++] = 0x01;   //DTCSnapshotRecordNumber is fixed as 1
    pBuf[u8_lenght++] = 0x03;   //DTCSnapshotRecordNumberOfIdentifier is fixed as 3

    pBuf[u8_lenght++] = 0xA0;
    pBuf[u8_lenght++] = 0x02;
    pBuf[u8_lenght++] = s_dtcSnapShot[u8_dtc_index].BatteryVoltage;
    pBuf[u8_lenght++] = 0xA0;
    pBuf[u8_lenght++] = 0x03;
    pBuf[u8_lenght++] = s_dtcSnapShot[u8_dtc_index].Odograph[0];
    pBuf[u8_lenght++] = s_dtcSnapShot[u8_dtc_index].Odograph[1];
    pBuf[u8_lenght++] = s_dtcSnapShot[u8_dtc_index].Odograph[2];
    pBuf[u8_lenght++] = 0xA0;
    pBuf[u8_lenght++] = 0x01;
    pBuf[u8_lenght++] = s_dtcSnapShot[u8_dtc_index].IgnitionStatus;

#endif
    return u8_lenght;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_GetExtendDataDtcRecode
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/09/27, hui.liu create this function
 ****************************************************************************/
UINT8 UdsCallBack_GetExtendDataDtcRecode(UINT16 u16_dtc_index , UINT8* pBuf)
{
    UINT8 u8_lenght = 0;
    (void)u16_dtc_index;
    (void)pBuf;

#if 0
    pBuf[u8_lenght++] =  s_dtcExtRecord[u8_dtc_index].u8_agedCounter;
    pBuf[u8_lenght++] =  s_dtcExtRecord[u8_dtc_index].u8_ageingCounter;

#endif
    return u8_lenght;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_GetDtcListAndSts
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2015/09/02, hui.pang create this function
 ****************************************************************************/

extern  UINT8 diag_getDtcIndex(UINT8 high, UINT8 middle, UINT8 low);
UINT8 UdsCallBack_GetDtcIndex(UINT8 high, UINT8 middle, UINT8 low)
{


#if 1
    return diag_getDtcIndex(high, middle, low);
#endif
    return 0;
}

/*
**  Global Var:  s_DTC_Status
**  Description: 
**               
**  Author:      2016/09/27, hui.liu create this Variable
*/
static DTC_Data_S s_DTC_Status;

/****************************************************************************/
/**
 * Function Name: UdsCallBack_GetDtcListAndSts
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/09/27, hui.liu create this function
 ****************************************************************************/
DTC_Data_S UdsCallBack_GetDtcListAndSts(UINT16 u16_index)
{

	//(void)u16_index;

#if 1
    s_DTC_Status.high   = dtcLUT[u16_index][0];
    s_DTC_Status.middle = dtcLUT[u16_index][1];
    s_DTC_Status.low    = dtcLUT[u16_index][2];
    s_DTC_Status.status = dtcStatus[u16_index].status;

#endif
    return s_DTC_Status;
}

#endif// MODE_19_SUPPORTED

#ifdef MODE_28_SUPPORTED

/****************************************************************************/
/**
 * Function Name: UdsCallBack_CommCtrl
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2015/09/18, hui.pang create this function
 ****************************************************************************/
void UdsCallBack_CommCtrl( Uds_CanCommCtrlSts_E type, BOOL b_flag )
{
	(void)b_flag;

    if( COMM_APP_SEND == type )
    {
#if 1
         app_canTxCtrl(b_flag);
#endif
    }
    else if( COMM_APP_REC == type )
    {
#if 1
        app_canRxCtrl(b_flag);
#endif
    }
    else if( COMM_NWM_SEND == type )
    {

    }
    else if( COMM_NWM_REC == type )
    {

    }
    else
    {
        /* do nothing */
    }
}

#endif// MODE_28_SUPPORTED

#ifdef MODE_23_SUPPORTED

/****************************************************************************/
/**
 * Function Name: UdsCallBack_ReadMemory
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/10/17, hui.liu create this function
 ****************************************************************************/
BOOL UdsCallBack_ReadMemory( UINT32 u32_addr, UINT8 *p_u8_data, UINT16 u16_len )
{
    const UINT8 Encrypt[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
    
    UINT8 u8_resp = FALSE;
    UINT8 data;
    UINT16 i;
    
    (void)memcpy(p_u8_data, (UINT8*)u32_addr, u16_len);

    for(i=0; i<u16_len; i++)
    {
        data = p_u8_data[i];
        
        data = (data<<5)|(data>>3);
        data ^= Encrypt[i%8];
        data ^= (UINT8)(2*i+1);

        p_u8_data[i] = data;
    }
    
    u8_resp = TRUE;
    
    return u8_resp;
}

/****************************************************************************/
/**
 * Function Name: UdsCallBack_WriteMemory
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2016/10/17, hui.liu create this function
 ****************************************************************************/
BOOL UdsCallBack_WriteMemory( UINT32 u32_addr, UINT8 *p_u8_data, UINT16 u16_len )
{
    UINT8 u8_resp = FALSE;
    
    (void)u32_addr;
    (void)p_u8_data;
    (void)u16_len;
    
    
    return u8_resp;
}

#endif// MODE_23_SUPPORTED

#pragma CODE_SEG  DEFAULT

/*****************************************************************************
** End File
*****************************************************************************/

